#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

#include "InetAddr.hpp"

// "len"\r\n "{json}"\r\n --- 完整报文，
// \r\n 用来区分len json
static const std::string sep = "\r\n";

//添加报头
std::string Encode(const std::string& jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

//删除报头
std::string Decode(std::string& packagestream)
{
    //分析
    auto pos = packagestream.find(sep);
    if(pos == std::string::npos)
        return std::string();
    std::string lenstr = packagestream.substr(0,pos);
    int len = std::stoi(lenstr);
    int total = lenstr.size() + len + 2 * sep.size();
    if(packagestream.size() < total)
        return std::string();

    //提取
    std::string json = packagestream.substr(pos+sep.size(),len);
    packagestream.erase(total);
    return json;
}

class Request
{
public:
    Request()
    {
    }

    Request(int x, int y, int oper)
        : _x(x), _y(y), _oper(oper)
    {
    }

    ~Request()
    {
    }

    bool Serialize(std::string *out)
    {
        // 使用现成的库 jsoncpp
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::FastWriter w;
        // Json::StyledWriter w;
        std::string s = w.write(root);
        *out = s;
        return true;
    }

    bool Deserialize(const std::string &in)
    {
        Json::Reader read;
        Json::Value root;
        read.parse(in, root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();
        return true;
    }

    void Print()
    {
        std::cout << _x << std::endl;
        std::cout << _y << std::endl;
        std::cout << _oper << std::endl;
    }

    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response()
        :_result(0),_code(0),_desc("success")
    {
    }

    bool Serialize(std::string *out)
    {
        // 使用现成的库 jsoncpp
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc; 

        Json::FastWriter w;
        // Json::StyledWriter w;
        std::string s = w.write(root);
        *out = s;
        return true;
    }

    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader read;
        bool res = read.parse(in, root);
        if(!res)
            return false;
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();
        return true;
    }

    ~Response()
    {
    }

    int _result;
    int _code; // 0: succsee 1:div zero 2:非法操作
    std::string _desc;
};

class Factory
{
public:
    static std::shared_ptr<Request> BuidRequestDefault()
    {
        return std::make_shared<Request>();
    }

    static std::shared_ptr<Response> BuidResponseDefault()
    {
        return std::make_shared<Response>();
    }
};